package com.hand.wfive.loginAndVip.ui

import android.app.Activity
import android.content.Intent
import android.text.SpannableStringBuilder
import android.text.TextUtils
import android.view.View
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.hand.wfive.R
import com.hand.wfive.activity.MainActivity
import com.hand.wfive.ad.AdActivity
import com.hand.wfive.ad.AdConfig
import com.hand.wfive.dialog.CommonTipsDialog
import com.hand.wfive.dialog.ProgressLoadingDialog
import com.hand.wfive.loginAndVip.ApiConfig
import com.hand.wfive.loginAndVip.LoginConfig
import com.hand.wfive.loginAndVip.UserManager
import com.hand.wfive.loginAndVip.model.CouponModel
import com.hand.wfive.loginAndVip.model.UserEvent
import com.hand.wfive.loginAndVip.model.UserRefreshEvent
import com.hand.wfive.loginAndVip.model.VipConfigModel
import com.hand.wfive.loginAndVip.model.VipGoodsModel
import com.hand.wfive.util.BigDecimalManager
import com.hand.wfive.util.SharedPreferencesUtils
import com.hand.wfive.util.SpanUtils
import com.hand.wfive.util.ToastUtils
import com.hand.wfive.util.VipData

import com.rxjava.rxlife.RxLife
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.toast
import rxhttp.wrapper.param.RxHttp


/**
 * 统一价格配置数据接口，基础支付处理
 * @see BaseVipActivity 有活动优惠券直接继承该类
 *
 * QMUI相关弹窗提示等在Dialog样式的activity中，无法生效（上下文必须为activity）
 */
abstract class BasePayActivity : AdActivity() {

    companion object {
        /**
         * 会员活动请求
         */
        const val REQ_ID_VIP_ACTIVITY = 10001

        /**
         * 会员价格请求
         */
        const val REQ_ID_VIP_PRICE = 10002

        const val PAY_WAY_WECHAT = "wxpay"
        const val PAY_WAY_ALIPAY = "alipay"
    }

    enum class PageTypeEnum(val type: Int) {
        /**
         * 常规会员中心
         */
        PAGE_TYPE_VIP(2),

        /**
         * 弹窗会员页
         */
        PAGE_TYPE_DIALOG_VIP(3),

        /**
         * 保存购买页
         */
        PAGE_TYPE_SAVE(4),

        /** 弹窗挽留支付会员页**/
        PAGE_TYPE_DIALOG_RETENTION_VIP(5)
    }

    private var mQueryVipPriceByKey = LoginConfig.AppId
    protected val mVipConfigList = ArrayList<VipGoodsModel>() //会员价格列表
    protected var mCurVipModel: VipGoodsModel? = null //当前选中的会员卡
    protected var isHasCoupon = false //是否领取了优惠券

    private var mH5PayType = PAY_WAY_WECHAT
    private var mIsWechatAppPay = 0
    private var mIsAliAppPay = 0
    private lateinit var mTurnH5Pay: ActivityResultLauncher<Intent>

    private var mActivityStartTime = 0L
    protected lateinit var mSpUtils: SharedPreferencesUtils

    private var progressLoadingDialog: ProgressLoadingDialog? = null

    override fun init() {
        registerEventBus()
        mSpUtils = SharedPreferencesUtils(mContext, SharedPreferencesUtils.SP_NAME_CONSTANT)
        mActivityStartTime = mSpUtils.getValue(SharedPreferencesUtils.KEY_ACTIVITY_START_TIME, 0L)
        initViewData()
        mTurnH5Pay = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ) {
            if (it.resultCode == RESULT_OK) {
                showLoadingDialog(isCancelable = false)
                UserManager.getInstance().initUser()
            }
        }
        val vipConfigModel = VipData.getVipGoodsModel()

        if (getPageType() == PageTypeEnum.PAGE_TYPE_DIALOG_VIP.type
            && vipConfigModel != null && vipConfigModel.obj?.isNotEmpty() == true
        ) {
            mVipConfigList.clear()
            mVipConfigList.addAll(vipConfigModel.obj)
            setVipConfigSuccessData(vipConfigModel)
        } else if (getPageType() == PageTypeEnum.PAGE_TYPE_DIALOG_RETENTION_VIP.type) {
            onNetSuccess(REQ_ID_VIP_PRICE)
        } else if (getPageType() == PageTypeEnum.PAGE_TYPE_VIP.type){
            getVipPriceConfig()
        }
    }

    protected abstract fun getPageType(): Int
    protected abstract fun getView(): View
    protected abstract fun initViewData()

    protected abstract fun onNetSuccess(redId: Int)
    open fun onNetSuccessNoData(redId: Int) {}
    open fun onNetError(redId: Int) {}
    open fun deleteCurrentCoupon() {}
    open fun updateCurrentCoupon() {}

    open fun getSelectCoupon(): CouponModel? {
        return null
    }

    open fun getCurrentCouponModel(): CouponModel? {
        return null
    }

    protected fun getVipPriceConfig(isShowLoading: Boolean = true) {
        if (isShowLoading) {
            hideLoadingDialog()
            showLoadingDialog()
        }
        val param = RxHttp.postForm(ApiConfig.queryVipPriceByKey)
            .add("key", mQueryVipPriceByKey)
            .add("userId", UserManager.getInstance().userId)
            .add("isNewOld", 1)
            .add("bullet", "welcome_page")//返回isOpen开关
        param.asClass(VipConfigModel::class.java)
            .to(RxLife.toMain(this))
            .subscribe({ apiModel ->
                if (apiModel.code == ApiConfig.SUCCESSCODE) {
                    setVipConfigSuccessData(apiModel)
                } else {
                    showRetryDialog()
                    onNetSuccessNoData(REQ_ID_VIP_PRICE)
                }
                hideLoadingDialog()
            }, {
                hideLoadingDialog()
                showRetryDialog()
                onNetError(REQ_ID_VIP_PRICE)
            })
    }

    private fun setVipConfigSuccessData(apiModel: VipConfigModel) {
        VipData.setVipConfigModel(apiModel)
        mIsWechatAppPay = apiModel.isWechatAppPay
        mIsAliAppPay = apiModel.isAliAppPay
        mVipConfigList.clear()
        mVipConfigList.addAll(apiModel.obj)
        if (mVipConfigList.isEmpty()) {
            showRetryDialog()
        } else {
            mVipConfigList.forEachIndexed { index, vipGoodsModel ->
                if (vipGoodsModel.isSelect == 1) {
                    mCurVipModel = mVipConfigList[index] //默认选中
                }
            }
            if (mCurVipModel == null) {
                mCurVipModel = mVipConfigList[0]
            }
            updateCurrentCoupon()
            onNetSuccess(REQ_ID_VIP_PRICE)
        }
    }

    protected fun doPay(price: String, isWechatPay: Boolean, vipGoodsModel: VipGoodsModel? = mCurVipModel) {
        var payPrice = price
        if (isHasCoupon && (getCurrentCouponModel()?.couponStartTime ?: 0) >= 1000) { //领了优惠券并且优惠券未过期
            payPrice = getCurrentPrice(price)
        }
        if (TextUtils.isEmpty(payPrice) || TextUtils.equals("0", payPrice)) {
            showErrorToast("会员数据加载失败")
            return
        }
//        EventTrackingUtils.setTalkingDataEvent("vip_pay")
        startH5Pay(payPrice, if (isWechatPay) PAY_WAY_WECHAT else PAY_WAY_ALIPAY, vipGoodsModel = vipGoodsModel)
    }

    /**
     * 获取剩余的倒计时时间 如果剩余时间、<=0,则会返回总的倒计时时间 重新开始计时
     * @param timeType 1:活动时间， 2：优惠券时间
     */
    protected fun getRemainderTime(
        totalDownTimeMillisecond: Long,
        timeType: Int,
        couponStartTime: Long = getSelectCoupon()?.couponStartTime ?: 0L,
    ): Long {
        val startTime = if (timeType == 1) {
            mActivityStartTime
        } else {
            couponStartTime
        }
        val usedTime = System.currentTimeMillis() - startTime
        var remainderTime = totalDownTimeMillisecond
        if (usedTime < totalDownTimeMillisecond) {
            //如果已消耗的时长 < 总倒计时长 ,则总倒计时长 - 已使用时长继续计时
            remainderTime = totalDownTimeMillisecond - usedTime
        } else {
            if (timeType == 1)
                saveActivityStartTime(SharedPreferencesUtils.KEY_ACTIVITY_START_TIME)
            else {
                deleteCurrentCoupon()
            }
        }
        return remainderTime
    }

    /**
     * 保存活动计时开始时间戳
     */
    private fun saveActivityStartTime(spKey: String) {
        mSpUtils.putValue(spKey, System.currentTimeMillis())
    }

    protected fun setPriceStyle(price: String): SpannableStringBuilder {
        val span = SpanUtils()
        span.append("¥").setFontSize(14, true)
            .append(price)
        return span.create()
    }

    /**
     * 获取当前选中的会员价格（未减去活动优惠券的价格）
     */
    protected fun getSelectPrice(): String? {
        for (i in mVipConfigList.indices) {
            val model = mVipConfigList[i]
            if (TextUtils.equals(mCurVipModel?.accName, model.accName)) {
                return model.productPrice
            }
        }
        return "0"
    }

    /**
     * 获取当前实际需要支付的价格 （会员卡价格 - 优惠券价格）
     */
    protected fun getCurrentPrice(originPrice: String): String {
        if (TextUtils.isEmpty(originPrice)) {
            return ""
        }
        val coupon = getSelectCoupon()
        val couponPrice = coupon?.price ?: "0"
        var payPrice = try {
            BigDecimalManager.subtractionDoubleToStr(originPrice.toDouble(), couponPrice.toDouble(), 2)
        } catch (e: Exception) {
            originPrice
        }
        if (payPrice == null || payPrice.isEmpty() || payPrice.toDouble() < 0) {
            payPrice = originPrice
        }
        return payPrice
    }

    private fun startH5Pay(price: String, type: String = PAY_WAY_WECHAT, vipGoodsModel: VipGoodsModel? = mCurVipModel) {
        mH5PayType = type
        /*
          http://www.quexingnet.cn/m/orderApi/view?
          code=2666236898829_1979_huawei
          &amount=0.01
          &name=学拼音发音点读
          &remark=永久会员-学拼音发音点读
          &appid=627b114030a4f67780d3e779
          &vipType=0
          &username=test1234
          &userid=1111
          &type=alipay or wxpay
          */
        var payPrice = price
        /*if (BuildConfig.DEBUG){
            payPrice = "0.01"
        }*/
        val name = getString(R.string.app_name)
        val remark = "${vipGoodsModel?.accName}-$name"
        val vipTimes =
            if (TextUtils.isEmpty(vipGoodsModel?.cardDayNum)) 0 else vipGoodsModel?.cardDayNum //天卡天数
        //ps : 如果存在次卡需要加参数，但是由于次卡需要修改代码支持，此处也先不预埋

        val user = UserManager.getInstance().curUser
        val orderUrl = ApiConfig.basePayUrl + "orderApi/view?" +
                "code=${getOutTradeNo()}&amount=${payPrice}&name=${remark}" +
                "&remark=${remark}&appid=${LoginConfig.AppId}" +
                "&vipType=${vipGoodsModel?.productKey}&vipTimes=${vipTimes}" +
                "&username=${user.username}&userid=${user.id}&type=${mH5PayType}"
        mTurnH5Pay.launch(H5PayActivity.showIntent(mContext, orderUrl, mH5PayType))
    }

    /**
     * 生成订单号
     */
    private fun getOutTradeNo(): String {
        val randomInt = ((Math.random() * 9 + 1) * 1000).toInt()
        return "${System.currentTimeMillis()}_${randomInt}_${getString(R.string.channel)}"
    }

    protected fun goToMainActivity() {
        startActivity<MainActivity>()
        finish()
    }

    private fun showRetryDialog() {
        CommonTipsDialog.showDialog(mContext,
            content = "会员数据加载失败",
            rightText = "重试",
            listener = object : CommonTipsDialog.TipListener {
                override fun doLeftEvent(dialog: CommonTipsDialog) {
                    finish()
                }

                override fun doRightEvent(dialog: CommonTipsDialog) {
                    getVipPriceConfig()
                }
            })
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun doUserEvent1(event: UserEvent) {
        if (getPageType() == PageTypeEnum.PAGE_TYPE_SAVE.type) {
            if (UserManager.getInstance().isVip || UserManager.getInstance().vipTimes > 0) {
                openFuncVipSuccess()
            }
        } else {
            if (UserManager.getInstance().isVip) {
                toast("会员开通成功")
                AdConfig.isShowAd = false
                setResult(Activity.RESULT_OK)
                finish()
            }
        }
    }

    protected open fun openFuncVipSuccess() {

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun doUserRefreshEvent(event: UserRefreshEvent) {
        hideLoadingDialog()
    }

    protected fun showSuccessToast(msg: String) {
        if (isDialogStyle()) {
            ToastUtils.showSuccessTip(msg)
        } else {
            showSuccessTip(getView(), msg)
        }
    }

    protected fun showNormalToast(msg: String) {
        if (isDialogStyle()) {
            ToastUtils.showNormalTip(msg)
        } else {
            showNormalTip(getView(), msg)
        }
    }

    protected fun showErrorToast(msg: String) {
        if (isDialogStyle()) {
            ToastUtils.showErrorTip(msg)
        } else {
            showErrorTip(getView(), msg)
        }
    }

    private fun showLoadingDialog(tipMessage: String = "请稍后...", isCancelable: Boolean = false) {
        if (isDialogStyle()) {
            progressLoadingDialog = ProgressLoadingDialog(mContext, tipMessage, isCancelable)
            progressLoadingDialog?.show()
        } else {
            if (isCancelable) {
                showLoading(tipMessage)
            } else {
                showLoadingC(tipMessage)
            }
        }
    }

    private fun hideLoadingDialog() {
        progressLoadingDialog?.dismiss()
        hideLoading()
    }


    /**
     * 是否是dialog主题的页面（处理QMUIDialog无法正常弹出问题）
     */
    private fun isDialogStyle(): Boolean {
        return getPageType() == PageTypeEnum.PAGE_TYPE_DIALOG_VIP.type || getPageType() == PageTypeEnum.PAGE_TYPE_DIALOG_RETENTION_VIP.type
    }
}